\chapter{RISC-V Assembly Programmer's Handbook}
\label{assembly}

This chapter is a placeholder for an assembly programmer's manual.

Table~\ref{regmap} lists the assembler mnemonics for the {\tt x} and {\tt f}
registers and their role in the first standard calling convention.

\vspace{0.2in}
\begin{table*}[htbp]
\begin{center}
\begin{tabular}{|l|l|l|l|}

  \hline
  Register            & ABI Name            & Description        & Saver \\ \hline
  \tt x0              & \tt zero            & Hard-wired zero    & --- \\
  \tt x1              & \tt ra              & Return address     & Caller \\
  \tt x2              & \tt sp              & Stack pointer      & Callee \\
  \tt x3              & \tt gp              & Global pointer     & --- \\
  \tt x4              & \tt tp              & Thread pointer     & --- \\
  \tt x5              & {\tt t0}            & Temporary/alternate link register& Caller \\
  {\tt x6}--{\tt 7}   & {\tt t1}--{\tt 2}   & Temporaries        & Caller \\
  \tt x8              & {\tt s0}/\tt fp     & Saved register/frame pointer & Callee \\
  \tt x9              & {\tt s1}            & Saved register     & Callee \\
  {\tt x10}--{\tt 11} & {\tt a0}--{\tt 1}   & Function arguments/return values & Caller \\
  {\tt x12}--{\tt 17} & {\tt a2}--{\tt 7}   & Function arguments & Caller \\
  {\tt x18}--{\tt 27} & {\tt s2}--{\tt 11}  & Saved registers    & Callee \\
  {\tt x28}--{\tt 31} & {\tt t3}--{\tt 6}   & Temporaries        & Caller \\
  \hline
  {\tt f0}--{\tt 7}   & {\tt ft0}--{\tt 7}  & FP temporaries     & Caller \\
  {\tt f8}--{\tt 9}   & {\tt fs0}--{\tt 1}  & FP saved registers & Callee \\
  {\tt f10}--{\tt 11} & {\tt fa0}--{\tt 1}  & FP arguments/return values & Caller \\
  {\tt f12}--{\tt 17} & {\tt fa2}--{\tt 7}  & FP arguments       & Caller \\
  {\tt f18}--{\tt 27} & {\tt fs2}--{\tt 11} & FP saved registers & Callee \\
  {\tt f28}--{\tt 31} & {\tt ft8}--{\tt 11} & FP temporaries     & Caller \\
  \hline

 \end{tabular}
\end{center}
\caption{Assembler mnemonics for RISC-V integer and floating-point
  registers, and their role in the first standard calling convention.}
\label{regmap}
\end{table*}

\pagebreak

\begin{commentary}
  There may be future different calling conventions, but note that
  registers {\tt x1}, {\tt x2}, and {\tt x5} have special meanings
  encoded in the standard ISA and/or the compressed extension.
\end{commentary}

Tables~\ref{pseudos} and \ref{csr-pseudos} contain a listing of standard
RISC-V pseudoinstructions.

\begin{table}[h]
\begin{small}
\begin{center}
\begin{tabular}{l l l}
pseudoinstruction & Base Instruction(s) & Meaning \\ \hline

\tt la rd, symbol (\emph{non-PIC}) & {\tt auipc rd, ${\tt delta[31:12]} + {\tt delta[11]}$} & Load absolute address, \\
                  & {\tt addi rd, rd, delta[11:0]}                         & where ${\tt delta} = {\tt symbol} - {\tt pc}$ \\[1ex]
\tt la rd, symbol (\emph{PIC})& {\tt auipc rd, ${\tt delta[31:12]} + {\tt delta[11]}$} & Load absolute address, \\
                  & {\tt l\{w|d\} rd, rd, delta[11:0]}                         & where ${\tt delta} = {\tt GOT[symbol]} - {\tt pc}$ \\[1ex]
\tt lla rd, symbol& {\tt auipc rd, ${\tt delta[31:12]} + {\tt delta[11]}$} & Load local address, \\
                  & {\tt addi rd, rd, delta[11:0]}                         & where ${\tt delta} = {\tt symbol} - {\tt pc}$ \\[1ex]
\tt l\{b|h|w|d\} rd, symbol & {\tt auipc rd, ${\tt delta[31:12]} + {\tt delta[11]}$} & Load global \\
                            & {\tt l\{b|h|w|d\} rd, delta[11:0](rd)}                 & \\[1ex]
\tt s\{b|h|w|d\} rd, symbol, rt & {\tt auipc rt, ${\tt delta[31:12]} + {\tt delta[11]}$} & Store global \\
                               & {\tt s\{b|h|w|d\} rd, delta[11:0](rt)}                 & \\[1ex]
\tt fl\{w|d\} rd, symbol, rt & {\tt auipc rt, ${\tt delta[31:12]} + {\tt delta[11]}$} & Floating-point load global \\
                             & {\tt fl\{w|d\} rd, delta[11:0](rt)}                    & \\[1ex]
\tt fs\{w|d\} rd, symbol, rt & {\tt auipc rt, ${\tt delta[31:12]} + {\tt delta[11]}$} & Floating-point store global \\
                             & {\tt fs\{w|d\} rd, delta[11:0](rt)}                    & \\[1ex]
\multicolumn{3}{p{.99\textwidth}}{\small \em The base instructions use {\tt pc}-relative addressing, so the linker subtracts {\tt pc} from {\tt symbol} to get {\tt delta}.  The linker adds {\tt delta[11]} to the 20-bit high part, counteracting sign extension of the 12-bit low part.} \\
~\\
\hline
{\tt nop} & {\tt addi x0, x0, 0} & No operation \\
{\tt li rd, immediate} & {\em Myriad sequences} & Load immediate \\
{\tt mv rd, rs} & {\tt addi rd, rs, 0} & Copy register \\
{\tt not rd, rs} & {\tt xori rd, rs, -1} & One's complement \\
{\tt neg rd, rs} & {\tt sub rd, x0, rs} & Two's complement \\
{\tt negw rd, rs} & {\tt subw rd, x0, rs} & Two's complement word \\
{\tt sext.w rd, rs} & {\tt addiw rd, rs, 0} & Sign extend word \\
{\tt seqz rd, rs} & {\tt sltiu rd, rs, 1} & Set if $=$ zero \\
{\tt snez rd, rs} & {\tt sltu rd, x0, rs} & Set if $\neq$ zero \\
{\tt sltz rd, rs} & {\tt slt rd, rs, x0} & Set if $<$ zero \\
{\tt sgtz rd, rs} & {\tt slt rd, x0, rs} & Set if $>$ zero \\
\hline
{\tt fmv.s rd, rs} & {\tt fsgnj.s rd, rs, rs} & Copy single-precision register \\
{\tt fabs.s rd, rs} & {\tt fsgnjx.s rd, rs, rs} & Single-precision absolute value \\
{\tt fneg.s rd, rs} & {\tt fsgnjn.s rd, rs, rs} & Single-precision negate \\
{\tt fmv.d rd, rs} & {\tt fsgnj.d rd, rs, rs} & Copy double-precision register \\
{\tt fabs.d rd, rs} & {\tt fsgnjx.d rd, rs, rs} & Double-precision absolute value \\
{\tt fneg.d rd, rs} & {\tt fsgnjn.d rd, rs, rs} & Double-precision negate \\
\hline
{\tt beqz rs, offset} & {\tt beq rs, x0, offset} & Branch if $=$ zero \\
{\tt bnez rs, offset} & {\tt bne rs, x0, offset} & Branch if $\neq$ zero \\
{\tt blez rs, offset} & {\tt bge x0, rs, offset} & Branch if $\leq$ zero \\
{\tt bgez rs, offset} & {\tt bge rs, x0, offset} & Branch if $\geq$ zero \\
{\tt bltz rs, offset} & {\tt blt rs, x0, offset} & Branch if $<$ zero \\
{\tt bgtz rs, offset} & {\tt blt x0, rs, offset} & Branch if $>$ zero \\
\hline
{\tt bgt rs, rt, offset} & {\tt blt rt, rs, offset} & Branch if $>$ \\
{\tt ble rs, rt, offset} & {\tt bge rt, rs, offset} & Branch if $\leq$ \\
{\tt bgtu rs, rt, offset} & {\tt bltu rt, rs, offset} & Branch if $>$, unsigned \\
{\tt bleu rs, rt, offset} & {\tt bgeu rt, rs, offset} & Branch if $\leq$, unsigned \\
\hline

\end{tabular}
\end{center}
\end{small}
\caption{RISC-V pseudoinstructions.}
\label{pseudos}
\end{table}

\begin{table}[h]
\begin{small}
\begin{center}
\begin{tabular}{l l l}
pseudoinstruction & Base Instruction & Meaning \\ \hline

{\tt j offset} & {\tt jal x0, offset} & Jump \\
{\tt jal offset} & {\tt jal x1, offset} & Jump and link \\
{\tt jr rs} & {\tt jalr x0, 0(rs)} & Jump register \\
{\tt jalr rs} & {\tt jalr x1, 0(rs)} & Jump and link register \\
{\tt ret} & {\tt jalr x0, 0(x1)} & Return from subroutine \\
\tt call offset & {\tt auipc x1, ${\tt offset[31:12]} + {\tt offset[11]}$} & Call far-away subroutine \\
                & {\tt jalr x1, offset[11:0](x1)}                          & \\
\tt tail offset & {\tt auipc x6, ${\tt offset[31:12]} + {\tt offset[11]}$} & Tail call far-away subroutine \\
                & {\tt jalr x0, offset[11:0](x6)}                          & \\
\hline
{\tt fence} & {\tt fence iorw, iorw} & Fence on all memory and I/O \\
\hline
{\tt rdinstret[h] rd} & {\tt csrrs rd, instret[h], x0} & Read instructions-retired counter \\
{\tt rdcycle[h] rd} & {\tt csrrs rd, cycle[h], x0} & Read cycle counter \\
{\tt rdtime[h] rd} & {\tt csrrs rd, time[h], x0} & Read real-time clock \\
\hline
{\tt csrr rd, csr} & {\tt csrrs rd, csr, x0} & Read CSR \\
{\tt csrw csr, rs} & {\tt csrrw x0, csr, rs} & Write CSR \\
{\tt csrs csr, rs} & {\tt csrrs x0, csr, rs} & Set bits in CSR \\
{\tt csrc csr, rs} & {\tt csrrc x0, csr, rs} & Clear bits in CSR \\
\hline
{\tt csrwi csr, imm} & {\tt csrrwi x0, csr, imm} & Write CSR, immediate \\
{\tt csrsi csr, imm} & {\tt csrrsi x0, csr, imm} & Set bits in CSR, immediate \\
{\tt csrci csr, imm} & {\tt csrrci x0, csr, imm} & Clear bits in CSR, immediate \\
\hline
{\tt frcsr rd} & {\tt csrrs rd, fcsr, x0} & Read FP control/status register \\
{\tt fscsr rd, rs} & {\tt csrrw rd, fcsr, rs} & Swap FP control/status register \\
{\tt fscsr rs} & {\tt csrrw x0, fcsr, rs} & Write FP control/status register \\
\hline
{\tt frrm rd} & {\tt csrrs rd, frm, x0} & Read FP rounding mode \\
{\tt fsrm rd, rs} & {\tt csrrw rd, frm, rs} & Swap FP rounding mode \\
{\tt fsrm rs} & {\tt csrrw x0, frm, rs} & Write FP rounding mode \\
\hline
{\tt frflags rd} & {\tt csrrs rd, fflags, x0} & Read FP exception flags \\
{\tt fsflags rd, rs} & {\tt csrrw rd, fflags, rs} & Swap FP exception flags \\
{\tt fsflags rs} & {\tt csrrw x0, fflags, rs} & Write FP exception flags \\
\hline

\end{tabular}
\end{center}
\end{small}
\caption{RISC-V pseudoinstructions.}
\label{csr-pseudos}
\end{table}
